/**
 * 
 */
package com.shuqi.common.http;

import java.util.Map;

import org.apache.http.HttpVersion;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

import com.shuqi.common.utils.HttpUtils;
import com.shuqi.common.utils.JsonUtils;
import com.shuqi.common.utils.StringUtils;

/**
 * HTTP请求
 * 
 * @author li.li
 * 
 * @date 2014-06-24
 */
public class HttpProvider {
    private static HttpProvider instance = new HttpProvider();
    private DefaultHttpClient client;

    private HttpProvider() {

        // 基本参数
        HttpParams httpParams = new BasicHttpParams();
        HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(httpParams, HttpUtils.ENCODING);

        // 设置超时时间
        ConnManagerParams.setTimeout(httpParams, HttpUtils.COMMON_TIMEOUT);
        HttpConnectionParams.setConnectionTimeout(httpParams, HttpUtils.COMMON_CONNECT_TIMEOUT);
        HttpConnectionParams.setSoTimeout(httpParams, HttpUtils.COMMON_SO_TIMEOUT);

        // 创建HTPP实例
        client = new DefaultHttpClient(httpParams);

        // 设置拦截器
        client.addRequestInterceptor(new ShuqiHttpRequestInterceptor());
        client.addResponseInterceptor(new ShuqiHttpResponseInterceptor());

    }

    /**
     * 创建建使用默认超时时间的实例
     * 
     * @return
     */
    public static HttpProvider getInstance() {

        return instance;
    }

    /**
     * get请求
     * 
     * @param url 请求地址
     * @param params 参数
     * @param clazz 返回的对象实例类型
     * @return
     */
    public <T> T get(String url, Map<String, String> headers, Map<String, String> params,
            Class<T> clazz) {

        HttpResult httpResult = null;

        try {
            httpResult = get(url, headers, params);

            return j2o(httpResult, clazz);

        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            if (httpResult != null && httpResult.getRequest() != null)
                httpResult.getRequest().abort();// 释放连接
        }

        return null;
    }

    /**
     * post请求
     * 
     * @param url 请求地址
     * @param params 参数
     * @param clazz 返回的对象实例类型
     * @return
     */
    public <T> T post(String url, Map<String, String> headers, Map<String, String> params,
            Class<T> clazz) {

        HttpResult httpResult = null;

        try {
            httpResult = post(url, headers, params);

            return j2o(httpResult, clazz);

        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            if (httpResult != null && httpResult.getRequest() != null)
                httpResult.getRequest().abort(); // 释放连接

        }

        return null;


    }

    /**
     * 发送get请求
     * 
     * @param url
     * @param headers
     * @param params
     * @return
     * @throws Throwable
     */
    public HttpResult get(String url, Map<String, String> headers, Map<String, String> params)
            throws Throwable {

        HttpResult result = HttpUtils.get(client, url, headers, params);
        
        return result;
    }

    /**
     * 发送post请求
     * 
     * @param url
     * @param headers
     * @param params
     * @return
     * @throws Throwable
     */
    public HttpResult post(String url, Map<String, String> headers, Map<String, String> params)
            throws Throwable {

        HttpResult result = HttpUtils.post(client, url, headers, params);

        return result;
    }

    /**
     * 关闭线程池
     */
    public void shutdown() {
        if (client != null)
            client.getConnectionManager().shutdown();

    }

    /**
     * json转对象
     * 
     * @param httpResult
     * @param clazz
     * @return
     */
    private <T> T j2o(HttpResult httpResult, Class<T> clazz) {

        if (httpResult == null)
            return null;

        String result = httpResult.httpEntityContent();

        if (StringUtils.isBlank(result))
            return null;

        T obj = JsonUtils.fromJson(result, clazz);

        return obj;
    }

}
